using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace Jabr.Logic.Serialization
{
    sealed class Serializer
    {
        static private Serializer _instance = null;
        static private readonly object _padlock = new object();

        private MemoryStream _stream;
        private Encapsulator _encapsulator;
        private XmlSerializer _serializer;
        private XmlTextWriter _writer;
        private UTF8Encoding _encoder;

        private Serializer()
        {
            this._encapsulator = new Encapsulator();
            this._serializer = new XmlSerializer(this._encapsulator.GetType());
            this._encoder = new UTF8Encoding();
        }

        public string Serialize(object obj)
        {
            this._encapsulator.Object = obj;
            this._stream = new MemoryStream();
            this._writer = new XmlTextWriter(this._stream, Encoding.UTF8);
            this._serializer.Serialize(this._writer, this._encapsulator);
            this._stream.Seek(0, SeekOrigin.Begin);
            TextReader tr = new StreamReader(this._stream, true);
            return tr.ReadToEnd() + "\r\n";
        }

        public object Deserialize(string xml)
        {
            this._stream = new MemoryStream();
            Byte[] a = this._encoder.GetBytes(xml);
            this._stream.Write(a, 0, a.Length);
            this._stream.Seek(0, SeekOrigin.Begin);
            TextReader tr = new StreamReader(this._stream, true);
            var e = (Encapsulator)this._serializer.Deserialize(tr);
            return e.Object;
        }

        public static Serializer Instance
        {
            get
            {
                lock (Serializer._padlock)
                {
                    if (Serializer._instance == null)
                    {
                        Serializer._instance = new Serializer();
                    }
                    return Serializer._instance;
                }
            }
        }
    }
}
